/**
 * Copyright (C) 2011 KingCore Science & Technology CO,.LTD. All rights reserved.
 * XNS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

/**
 * Copyright (C) 2002-2011 WUZEWEN. All rights reserved.
 * WUZEWEN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * This software is the confidential and proprietary information of
 * WuZeven, Personal. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with WuZeven.
 */

package com.kingcore.director.resourcemaster.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Event;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.sql.RowSet;
import javax.swing.DefaultCellEditor;
import javax.swing.DropMode;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.apache.log4j.Logger;

import wzw.beans.DbBean;
import wzw.sql.DatabaseOperator;
import wzw.swing.table.IconTableCellRenderer;
import wzw.swing.table.PlainTable;
import wzw.swing.table.PlainTableModel;
import wzw.swing.table.ZebraCrossTableCellRenderer;
import wzw.swing.tree.PlainTree;
import wzw.swing.tree.PlainTreeModel;
import wzw.util.I18nUtil;
import wzw.util.I18nUtils;
import wzw.util.StringUtils;

import com.kingcore.director.DirectorConstants;
import com.kingcore.director.base.ui.DirectorPanel;
import com.kingcore.director.core.bean.TreeNodeBean;
import com.kingcore.director.core.util.DirectorComponentUtils;
import com.kingcore.director.core.util.DirectorFileUtils;
import com.kingcore.director.main.Main;
import com.kingcore.director.main.MainFrame;
import com.kingcore.director.resourcemaster.dao.FavoriteFilesDao;
import com.kingcore.director.resourcemaster.dao.impl.FavoriteFilesDaoImpl;
import com.kingcore.framework.util.DateUtil;
import com.sunking.swing.JFileTree;
import com.sunking.swing.JFileTree.AllFileFilter;
import com.sunking.swing.JTreeComboBox;

/**
 * <p>常用文件及文件夹的管理。
 *     为什么不做网络地址url的管理呢，因为url的管理做成B/S版本最好，C/S版本反而不适合做。</p>
 * @author Zeven on 2011-3-8
 * @version	1.0
 * @see		Object#equals(java.lang.Object)
 * @since	JDK5
 */

public class FavoriteFilesMainPanel extends DirectorPanel implements DatabaseOperator,
		ItemListener, ActionListener, MouseListener, MouseMotionListener, ChangeListener, KeyListener, CellEditorListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// log object
	private final static Logger log = Logger.getLogger(FavoriteFilesMainPanel.class);

	private MainFrame mainFrame = null;
	private JSplitPane mainSplitPane = null;
	private JSplitPane bottomSplitPane = null;
	private static final int MainSplitPane_Top_Height = 23;
	private static final int BottomSplitPane_Left_Width = 135; //wzw modify
	
	private static final int MainTable_Column_Index_Type = 0;
	private static final int MainTable_Column_Index_Tags = 1;
	private static final int MainTable_Column_Index_Name = 2;
	private static final int MainTable_Column_Index_Location = 3;
	private static final int MainTable_Column_Index_AccessedTimes = 4;
	private static final int MainTable_Column_Index_LastAccessedTime = 5;

//	private static final int MainTable_Column_Count = 5;
//	private static final int Search_Result_Max_Num = 1500;

	public static final String[] MainTable_Headers = {"Type", "Tags", "Name", "Location", "Times", "LastAccessed"}; //, "LastAccessed"
	public static final String[] MainTable_DbColumn = {"Type", "Tags", "Name", "Location", "Times", "LastAccessed"};
	public static final int[] MainTable_Columns_Width = { DirectorConstants.Min_TableColumn_Width, 120, 255, Main.MainFrame_Size_Width-(BottomSplitPane_Left_Width)-120-255 - DirectorConstants.Min_TableColumn_Width*2, DirectorConstants.Min_TableColumn_Width, 0}; //DirectorConstants.Table_TimeColumn_Width

	@Override
	public void refreshView() {
		super.refreshView();

		setStatus(StatusBar_Index_One, currentStatusInfor);
		getSearchWordTextFeild().setFocusable(true); 
		getSearchWordTextFeild().requestFocusInWindow();

		//		getStatusBar().repaint();
//		getStatusBar().validate();
//		getStatusBar().revalidate();  //刷新并显示
//		getStatusBar().setVisible(true); 
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(Calendar.getInstance().getTime());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Calendar.getInstance().getTime());
	

	}

	public FavoriteFilesMainPanel(MainFrame mainFrame) {
		super(mainFrame);

		this.mainFrame = mainFrame;
		initializeInterface();
		try {
			fetchData();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		this.addKeyListener(this);

		//this.update(null, null);  //move to end
		constructAfter();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initializeInterface() {
		// BorderLayout ...
		this.setLayout(new BorderLayout());

//		this.add(getToolBar(), BorderLayout.NORTH);   //收藏管理暂时不要工具栏
		this.add( getMainSplitPane(), BorderLayout.CENTER);
		this.add( getStatusBar(true), BorderLayout.SOUTH);

		this.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) {
				// log.info( this.getClass()+"------------- resize..."+
				// getWidth()+"X"+getHeight());
				// int panelWidth = getWidth();
				// int panelHeight = getHeight();
				// scrollPane.setBounds(new java.awt.Rectangle(1,130,
				// panelWidth-0,
				// panelHeight -128 ));
				// scrollPane.setViewportView(getTable());
				// repaint();
				getSearchWordTextFeild().setFocusable(true); 
				getSearchWordTextFeild().requestFocus();
			}
			
//			public void componentShown(ComponentEvent e) {
//				log.debug("panel:shown"); 	
//				//refreshView();  // 不建议这调用，事件不可靠，在上层tabpage切换时候主动调用。
//			}
		});
	}

	private JPanel mainTopPanel = null;

	private JLabel lbl_location=null;
	private JLabel lbl_tags=null;
	private JLabel lbl_find=null;
	private JLabel lbl_note=null;
	private JCheckBox includeDocumentCheckBox = null;
	private JCheckBox includeProgramCheckBox = null;

	/**
	 * This method initializes jContentPane
	 *  
	 * @return javax.swing.JPanel
	 */
	private JPanel getMainTopPanel() {
		if (mainTopPanel == null) {
			lbl_tags = new JLabel();
			lbl_tags.setBounds(new java.awt.Rectangle(5,1,33,23));
			lbl_tags.setText("Tags:");
			lbl_location = new JLabel();
			lbl_location.setBounds(new java.awt.Rectangle(207,1,90,23));
			lbl_location.setText("File Location:");
			mainTopPanel = new JPanel();
			mainTopPanel.setLayout(null);
			mainTopPanel.add(lbl_tags, null);
			mainTopPanel.add(lbl_location, null);
			mainTopPanel.add(getUrlSelector(), null);
			mainTopPanel.add(getTagsTextFeild(), null);
			mainTopPanel.add(getBtnAdd(), null);

			lbl_find = new JLabel("<html>Find(<u>F</u>):</html>");
			lbl_find.setBounds(new java.awt.Rectangle(585,1,45,23));
			lbl_find.putClientProperty("html.disable", Boolean.TRUE);
			
			lbl_note = new JLabel();
			lbl_note.setBounds(new java.awt.Rectangle(758,1,150,23));
			lbl_note.setText("(keywords link with blank)");

			//mainTopPanel.add(getIncludeDocumentCheckBox(), null);
			//mainTopPanel.add(getIncludeProgramCheckBox(), null);

			mainTopPanel.add(lbl_find, null);
			mainTopPanel.add(lbl_note, null);
			mainTopPanel.add(getSearchWordTextFeild(), null);
		}
		return mainTopPanel;
	}
	
//	/**
//	 * @deprecated
//	 * @return
//	 */
//	private JCheckBox getIncludeProgramCheckBox() {
//		if (includeProgramCheckBox == null) {
//			includeProgramCheckBox = new JCheckBox();
//			includeProgramCheckBox.setSelected(true);
//			includeProgramCheckBox.setBounds(new java.awt.Rectangle(965,9,80,23));
//			includeProgramCheckBox.setText("Program");
////			includeDocumentCheckBox.addChangeListener(this); //鼠标放上去就触发
//			includeProgramCheckBox.addItemListener(this);   //鼠标改变了对象状态才触发
//		}
//		return includeProgramCheckBox;
//	}
//
//	/**
//	 * @deprecated
//	 * @return
//	 */
//	private JCheckBox getIncludeDocumentCheckBox() {
//		if (includeDocumentCheckBox == null) {
//			includeDocumentCheckBox = new JCheckBox();
//			includeDocumentCheckBox.setSelected(true);
//			includeDocumentCheckBox.setBounds(new java.awt.Rectangle(883,8,85,25));
//			includeDocumentCheckBox.setText("Document");
//			includeDocumentCheckBox.addItemListener(this);
//		}
//		return includeDocumentCheckBox;
//	}

	private JButton btnAdd = null;
	/**
	 * This method initializes btnAdd	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtnAdd() {
		if (btnAdd == null) {
			btnAdd = new JButton();
			btnAdd.setBounds(new java.awt.Rectangle(492,0,80,24));
			btnAdd.setText("Add");
			btnAdd.addActionListener( this );
		}
		return btnAdd;
	}

	private JTextField tagsTextFeild = null;
	private JTextField getTagsTextFeild(){
		if (tagsTextFeild==null) {
			tagsTextFeild = new JTextField();
			tagsTextFeild.setBounds(new java.awt.Rectangle(42,0,150,25));
		}
		return tagsTextFeild;
	}
	
	private JTextField searchWordTextFeild = null;
	private JTextField getSearchWordTextFeild(){
		if (searchWordTextFeild==null) {
			searchWordTextFeild = new JTextField();
			searchWordTextFeild.setBounds(new java.awt.Rectangle(629,0,130,25));
			searchWordTextFeild.setToolTipText("Search word input(Ctrl+F)");
			searchWordTextFeild.getDocument().addDocumentListener(new DocumentListener(){
				public void insertUpdate(DocumentEvent e) {
	                 final String searchWord = searchWordTextFeild.getText();
	                 log.info("insertUpdate kw="+searchWord );
//	                 if (searchWord==null || searchWord.trim().length()<1) {
//	                 	return ;
//	                 }else{
////	         	    	SortableTableModel stm = (SortableTableModel)mainTable.getModel();
////	         	    	((DefaultTableModel)stm.getTableModel()).setRowCount(0);// 清除原有行
//	                 }
	                 
	                 doSearch(searchWord);
//	                 new Thread(){
//						  public void run() {
//				               doSearch(searchWord);  //启动新线程，增加用户体验，界面textField马上显示文字
//						  }
//	                 }.start();
	               // throw new UnsupportedOperationException("Not supported yet.");
	               // System.out.print("1");
	               // System.out.println(jTextField1.getText());
	            }

	            public void removeUpdate(DocumentEvent e) {
	                 final String searchWord = searchWordTextFeild.getText();
	                 log.info("removeUpdate kw="+searchWord );
//	                 if (searchWord==null || searchWord.trim().length()<1) {
//	                 	return ;
//	                 }else{  // following must out of new thread.
////	         	    	SortableTableModel stm = (SortableTableModel)mainTable.getModel();
////	         	    	((DefaultTableModel)stm.getTableModel()).setRowCount(0);// 清除原有行
//	                 }
	                 
		             doSearch(searchWord); 
//	                 new Thread(){
//						  public void run() {
//				               doSearch(searchWord);  //启动新线程，增加用户体验，界面textField马上显示文字
//						  }
//	                 }.start();
	                 
	            }

	            public void changedUpdate(DocumentEvent e) {
	                //JOptionPane.showMessageDialog(null, "请填写完整！");
	                 String searchWord = searchWordTextFeild.getText();
	                 log.info("kw="+searchWord);
	                 
	            }
	        });
			searchWordTextFeild.addKeyListener(this);
		}
		return searchWordTextFeild;
	}

	private int doSearch(String keyWord){
		return doSearch(keyWord, true);
	}
	
	// search: tags, namee.
	private int doSearch(String keyWord, boolean resortData){
		this.getMainTable().clearSelection();  // disselect all
		PlainTableModel ptm = this.getMainTable().getModel(); //
		int matchedNum = -1;
		if (keyWord==null || keyWord.trim().length()<1) {
			// 恢复默认按照时间排序状态。  说明：排序状态下修改tags等可能会无效。
			if (resortData) {
				ptm.setSortingStatus(MainTable_Column_Index_LastAccessedTime, PlainTableModel.DESCENDING);
			}
			//采用清除排序，避免对其他如tags更新产生影响，清除排序即使用默认的取数时候的上次访问时间的降序
			//ptm.cancelSorting();
			//ptm.setSortingStatus(MainTable_Column_Index_LastAccessedTime, PlainTableModel.NOT_SORTED);
			return matchedNum;
		}
		
		//ptm.setSortingStatus(MainTable_Column_Index_LastAccessedTime, PlainTableModel.DESCENDING);
		ptm.setSortingStatus(MainTable_Column_Index_LastAccessedTime, PlainTableModel.DESCENDING, true);
		//JOptionPane.showMessageDialog(this,"aa" ,"1",JOptionPane.ERROR_MESSAGE);
		ptm.cancelSorting();
		//JOptionPane.showMessageDialog(this,"aa" ,"2",JOptionPane.ERROR_MESSAGE);

		keyWord = keyWord.trim().toLowerCase();
		int rowCount = ptm.getRowCount(); //getMainTable().getRowCount();
		Object tags=null, fileUri=null ;
		String tagsStr=null, fileUriStr=null ;
		String[] keyWords = keyWord.split(" ");
		boolean notMatch = true;
		for (int i = 0; i < rowCount; i++) { //从上至下查找并移动，不会导致后面的index变化，而从下至上则会导致index变化。
			tags = ptm.getValueAt(i, MainTable_Column_Index_Tags);
			fileUri = ptm.getValueAt(i, MainTable_Column_Index_Location); //getMainTable()
			tagsStr = tags==null?null:tags.toString().toLowerCase();
			fileUriStr = fileUri==null?null:fileUri.toString().toLowerCase();
			notMatch = false;
			for (int j = 0; j < keyWords.length; j++) {
				keyWord = keyWords[j];
				if (keyWord==null || keyWord.trim().equals("")) {
					continue;
				}
				keyWord = keyWord.trim().toLowerCase();
				if ( (tagsStr!=null && tagsStr.indexOf(keyWord)>-1)
						|| (fileUriStr!=null && fileUriStr.indexOf(keyWord)>-1)) {
					continue;   // if ok,then next row.
				}else{
					notMatch = true;
					break;
				}
			}
			if (notMatch==false) {
				//getTable().addRowSelectionInterval(i, i); // set a selected	
				//DefaultTableModel dtm = (DefaultTableModel)ptm.getTableModel();
				matchedNum ++ ;
				ptm.moveRow(i, i, matchedNum); // move to the end of all matched.
			}	
		}
		if (matchedNum>-1) {  // end->set all selected rows.
			getMainTable().addRowSelectionInterval(0,matchedNum);
		}
		DirectorComponentUtils.scrollToRow(this.getMainTable(), 0);
		return matchedNum;
		
	}
    
	private JComboBox fileLocation = null;
	/**
	 * This method initializes path	,
	 * Zeven on 2007-03-21, add AllFileFilter not only Directory.
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getUrlSelector() {
		if (fileLocation == null) {
			fileLocation = new JTreeComboBox();  //JComboBox();
			fileLocation.setBounds(new java.awt.Rectangle(280,0,200,25)); //高度缩减2像素
			((JTreeComboBox)fileLocation).setTree(new JFileTree( new AllFileFilter()));
		}
		return fileLocation;
	}
 
	private JSplitPane getMainSplitPane() {
		if (mainSplitPane == null) {
			mainSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false);
			mainSplitPane.add(getMainTopPanel(), 0);
			mainSplitPane.add(getBottomSplitPane(), 1);
			mainSplitPane.setOneTouchExpandable(false);
			//mainSplitPane.setset
			mainSplitPane.setDividerSize(0); //2
			///mainSplitPane.setEnabled(false);  //设置这个会导致光标不变成输入状态
			mainSplitPane.setDividerLocation(MainSplitPane_Top_Height); // 200);
		}
		return mainSplitPane;
	}

	private JScrollPane leftScrollPane = null;
	/**
	 * This method initializes leftScrollPane
	 *
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getLeftScrollPane() {
		if (leftScrollPane == null) {
			leftScrollPane = new JScrollPane();
			//leftScrollPanel.setBounds(new java.awt.Rectangle(2, this.clientTop,150, this.clientHeight));
			leftScrollPane.setViewportView(getLeftTree());	//getJt_tree()
		}
		return leftScrollPane;
	}
	
	private JSplitPane getBottomSplitPane() {
		if (bottomSplitPane == null) {
			bottomSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
			bottomSplitPane.add( getLeftScrollPane(), 0);
			bottomSplitPane.add(getBottomScrollPane(), 1);
			bottomSplitPane.setOneTouchExpandable(true);
			//bottomSplitPane.setset
			bottomSplitPane.setDividerSize(5);
			bottomSplitPane.setDividerLocation(BottomSplitPane_Left_Width); // 200);
		}
		return bottomSplitPane;
	}
	private PlainTree tree = null;

    //定义几个初始节点  
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("所有分类");  
    DefaultMutableTreeNode allFav = new DefaultMutableTreeNode("所有收藏"); 
    DefaultMutableTreeNode sbj = new DefaultMutableTreeNode("学科类");   
    DefaultMutableTreeNode prj = new DefaultMutableTreeNode("项目类");   
    
    DefaultMutableTreeNode docs = new DefaultMutableTreeNode("所有文档");  
    DefaultMutableTreeNode pros = new DefaultMutableTreeNode("所有程序");  

    DefaultMutableTreeNode computer = new DefaultMutableTreeNode("计算机");  
    DefaultMutableTreeNode finance = new DefaultMutableTreeNode("经济学");  
    
    DefaultMutableTreeNode prj_vangv = new DefaultMutableTreeNode("VangV项目");  
    DefaultMutableTreeNode prj_om = new DefaultMutableTreeNode("OM项目");  
    
    //上面JTree对象对应的model  
    PlainTreeModel model;  
    //定义需要被拖动的TreePath  
    TreePath movePath;  
    
    private String Sql_GetClassesByPid = 
    	     new StringBuffer().append("Select class_id,class_name,pid,level_id,is_leaf,is_builtin,order_id")
							.append(" From ")
							.append(DirectorConstants.FMT_FavoriteFiles_Class)
							.append(" Where pid=?")
							.append(" Order by order_id asc")
							.toString();
	private PlainTree getLeftTree() {
		if(tree!=null)
			return tree;

//		allFav.add(docs);   
//		sbj.add(finance);   
//		prj.add(prj_vangv);  
//		prj.add(prj_om);   
//        root.add(allFav);  
//        root.add(prj);  
//        root.add(sbj);  
        
        DbBean dbBean = new DbBean(); 
		List<Object> list = null;
		List<Object> list2 = null;
		DefaultMutableTreeNode item = null; 
        try {
        	Object[] params = {0};
        	int[] paramTypes = {Types.INTEGER};//第1级
			list = dbBean.queryForList(Sql_GetClassesByPid, params , paramTypes, TreeNodeBean.class);
			for(Object obj : list){
				item = new DefaultMutableTreeNode(obj);
				if(((TreeNodeBean)obj).getClassId()== DirectorConstants.FavoriteFiles_ClassId_Default ){
					currentTreeNodeBean = (TreeNodeBean)obj;
				}
				root.add( item );

				Object[] params2 = {((TreeNodeBean)obj).getClassId()};
	        	int[] paramTypes2 = {Types.INTEGER};//第2级  
				list2 = dbBean.queryForList(Sql_GetClassesByPid,params2,paramTypes2,TreeNodeBean.class);//第2级
				for(Object obj2 : list2){
					item.add(new DefaultMutableTreeNode(obj2));
				}
			}
		} catch (SQLException e1) {
			log.error(e1);
			e1.printStackTrace();
		}
          
		tree = new PlainTree(root);  
        //获取JTree对应的TreeModel对象  
        model = (PlainTreeModel)tree.getModel();  
        //设置JTree可编辑  
        tree.setEditable(true);  
        MouseListener ml = new MouseAdapter()   
        {  
            //按下鼠标时候获得被拖动的节点  
            public void mousePressed(MouseEvent e)  
            {  
                //如果需要唯一确定某个节点，必须通过TreePath来获取。  
                TreePath tp = tree.getPathForLocation(e.getX(), e.getY());  
                if (tp != null)  
                {  
                    movePath = tp;  
                }  
            }  
            //鼠标松开时获得需要拖到哪个父节点  
            public void mouseReleased(MouseEvent e)  
            {  
                //根据鼠标松开时的TreePath来获取TreePath  
                TreePath tp = tree.getPathForLocation(e.getX(), e.getY());  
 
                if (tp != null && movePath != null)  
                {  
                    //阻止向子节点拖动  
                    if (movePath.isDescendant(tp) && movePath != tp)  
                    {  
                        JOptionPane.showMessageDialog( mainFrame, "目标节点是被移动节点的子节点，无法移动！",   
                            "非法操作", JOptionPane.ERROR_MESSAGE );  
                        return;  
                    }  
                    //既不是向子节点移动，而且鼠标按下、松开的不是同一个节点  
                    else if (movePath != tp)  
                    {  
                        System.out.println(tp.getLastPathComponent());  
                        //add方法可以先将原节点从原父节点删除，再添加到新父节点中  
                        ((DefaultMutableTreeNode)tp.getLastPathComponent()).add(  
                            (DefaultMutableTreeNode)movePath.getLastPathComponent());  
                        movePath = null;  
                        tree.updateUI();  
                    }  
                }  
            }  
        };    

	    tree.setRootVisible(false); //不显示根节点
	    expandTree(tree );
	    if (tree.getRowCount()>0) {
		    tree.setSelectionRow(0);
		}
    	tree.setEditable(false);
    	tree.updateUI();

        tree.addMouseListener( this ); //加监听器放最后面
        tree.addKeyListener( this );
        return tree;
	}
	
	/**
	 * 展开Tree的所有节点。
	 * @param tree
	 * @param parent
	 */
	public static void expandTree(JTree tree ) {
		expandTree(tree, new TreePath( (TreeNode) tree.getModel().getRoot() ) );
	}
	public static void expandTree(JTree tree, TreePath parent) {
	    TreeNode node = (TreeNode) parent.getLastPathComponent();
	    if (node.getChildCount() >= 0) {
	       for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
	           TreeNode n = (TreeNode) e.nextElement();
	           TreePath path = parent.pathByAddingChild(n);
	           expandTree(tree, path);
	       }
	    }
	    tree.expandPath(parent);

	}
	
	private JPanel topPanel = null;
	private JScrollPane rightScrollPanel = null;

	/**
	 * This method initializes leftScrollPane
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JPanel getTopPanel() {
		if (topPanel == null) {
			topPanel = new JPanel();
		}
		return topPanel;
	}
 
	/**
	 * This method initializes jPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JScrollPane getBottomScrollPane() {
		if (rightScrollPanel == null) {
			rightScrollPanel = new JScrollPane();
			// rightScrollPanel.setBounds(new
			// java.awt.Rectangle(158,this.clientTop,432, this.clientHeight));

			// rightScrollPanel.setLayout(new BorderLayout());
			// rightScrollPanel.setLayout( new BorderLayout() );
			rightScrollPanel.setViewportView( getMainTable() ); // getTable()
			// rightScrollPanel.setBackground(Color.gray);
			rightScrollPanel.setToolTipText("You can try dropping to add new files");
			
		}
		return rightScrollPanel;
	}

	private PlainTable mainTable = null;
	
	/**
	 * This method initializes table	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private PlainTable getMainTable(){
		if (mainTable==null) {
			mainTable = new PlainTable();	 
		    Object[][] data = {
		       {"Doc", "wangwin doc", "VangV_Tech_200801.doc", "D:/Documents", "2009-2-21 11:20:21", 5}
		    };
		    
		    // A DefaultTableModel object is created and initialized with some
		    // data and headers.

		    //DefaultTableModel dtm = new DefaultTableModel(2, 3);
		    //DefaultTableModel dtm = new UneditableTableModel(2, 3);
		    DefaultTableModel dtm = new DefaultTableModel(2, 3); //no new methods
		    dtm.setDataVector(data, MainTable_Headers );
		    PlainTableModel sorter = new PlainTableModel( dtm, mainTable.getTableHeader());
		    sorter.setColumnEditable( MainTable_Column_Index_Tags );
		    sorter.setColumnEditable( MainTable_Column_Index_Location , false);
//		    RowSorter sorter = new TableRowSorter(dtm);
		    sorter.setColumnClass(MainTable_Column_Index_AccessedTimes, java.lang.Integer.class);
		    mainTable.setModel(sorter);
		    
//		    table.setRowSorter(sorter);
		    
		    mainTable.setGridColor(Color.LIGHT_GRAY);
		    mainTable.setRowSelectionAllowed(true);
//		    if (mainTable.getRowCount()>0) {
//			    mainTable.setRowSelectionInterval(0, 0);	
//			}
		    mainTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

		    mainTable.setShowGrid(true);
		    mainTable.setRowHeight(23); //表行高
		    mainTable.getTableHeader().setReorderingAllowed(false);
		    mainTable.addMouseListener( this );
		    mainTable.addMouseMotionListener(this);		
	        mainTable.addKeyListener( this );    
		    this.refreshMainTable( false );

	        mainTable.setDropMode(DropMode.ON); //rightScrollPanel
	        //table.setDropTarget( mdt );
	        mainTable.setDropTarget( getThisDropTarget() );
	        mainTable.getModel().addTableModelListener(new TableModelListener(){
						String synStr = "demo";

						public void tableChanged(TableModelEvent e) {
							synchronized (synStr) {
								if (e.getType() == TableModelEvent.UPDATE) {
									/*
									 * do some thing 获得编辑后单元格得值
									 */
									if (e.getLastRow() > mainTable
											.getRowCount()
											|| e.getLastRow() < 0
											|| e.getColumn() < 0) {
										log.debug(e.getFirstRow() + " "
												+ e.getLastRow() + " "
												+ e.getColumn() + " "
												+ mainTable.getRowCount());
										return;
									}

									log.info("e.getFirstRow()="
											+ e.getFirstRow()
											+ "e.getLastRow()="
											+ e.getLastRow() + "e.getColumn()="
											+ e.getColumn());

									final int currentChangedColumnIndex = e
											.getColumn();
									if (currentChangedColumnIndex != MainTable_Column_Index_Tags
											&& currentChangedColumnIndex != MainTable_Column_Index_Location) {
										return;
									}
									final int currentRow = e.getLastRow();
									String fileName = "";// ""比null好
									final String newValue = mainTable
											.getValueAt(e.getLastRow(),
													currentChangedColumnIndex)
											.toString();
									Object oldValue = tableOldValueMap
											.get(currentChangedColumnIndex + "");
									if (oldValue == newValue // ||
																// newValue==null
											|| (newValue != null && newValue
													.equals(oldValue))) {
										return;
									}

									if (newValue != null) {
										log.info("newValue=" + newValue
												+ " oldValue=" + oldValue);

										// change file name
										String str_Location = null;
										String fileExtName = ""; // ""比null好
										final String val = mainTable
												.getValueAt(e.getLastRow(),
														currentChangedColumnIndex)
												.toString();
										String sql = null;
										if (currentChangedColumnIndex == MainTable_Column_Index_Location) {
											str_Location = tableOldValueMap
													.get(MainTable_Column_Index_Location
															+ "").toString();
											if (val.endsWith(File.separator)) {
												fileName = val.substring(
														val.lastIndexOf(File.separator) + 1,
														val.length() - 1);
											} else {
												fileName = val.substring(
														val.lastIndexOf(File.separator) + 1,
														val.length());
											}
											if (fileName != null
													&& fileName.indexOf(".") > 0) {
												fileExtName = fileName.substring(fileName
														.lastIndexOf(".")); // return
																			// as
																			// ".txt"
											}
											sql = "Update "
													+ DirectorConstants.FMT_FavoriteFiles
													+ " set "
													+ MainTable_DbColumn[currentChangedColumnIndex]
													+ "='" + val + "'"
													+ " ,Typee='" + fileExtName
													+ "'" + " ,Namee='"
													+ fileName + "'"
													+ " Where Location='"
													+ str_Location + "'";
											mainTable
													.setValueAt(fileExtName,
															currentRow,
															MainTable_Column_Index_Type);
											mainTable
													.setValueAt(fileName,
															currentRow,
															MainTable_Column_Index_Name);
										} else {
											str_Location = mainTable
													.getValueAt(e.getLastRow(),
															MainTable_Column_Index_Location)
													.toString();
											sql = "Update "
													+ DirectorConstants.FMT_FavoriteFiles
													+ " set "
													+ MainTable_DbColumn[currentChangedColumnIndex]
													+ "='" + val + "'"
													+ " Where Location='"
													+ str_Location + "'";
										}
										// else if
										// (currentChangedColumnIndex==MainTable_Column_Index_FileUri)
										// {
										// sql =
										// "Update "+DirectorConstants.FMT_FavoriteFiles+" set Location='"+val+"'"
										// +
										// " Where Location='"+fileUri+"'";
										// }

										log.info(sql);
										try {
											DbBean dbBean = new DbBean(
													DbBean.DefaultPoolName);
											dbBean.executeUpdate(sql);
											// 获取配置信息
											if (currentChangedColumnIndex == MainTable_Column_Index_Location) {
												mainTable
														.setValueAt(fileName,
																currentRow,
																MainTable_Column_Index_Name);
												PlainTableModel pModel = mainTable
														.getModel();
												pModel.setColumnEditable(
														MainTable_Column_Index_Location,
														false);
											}
										} catch (SQLException e1) {
											JOptionPane.showMessageDialog(
													mainFrame, e1.getMessage(),
													"数据库操作失败",
													JOptionPane.ERROR_MESSAGE);
											e1.printStackTrace();
											return;
										} finally {
											//
										}
										currentStatusInfor = msgDialog_infoSaveSuccess; // "Column value of "+MainTable_DbColumn[currentChangedColumnIndex]+" modified successfully!";
										setStatus(StatusBar_Index_One,
												currentStatusInfor);
									}

								}
							}
						}
					});
		}
		return mainTable;
		
	}

	DropTarget favoritesFIlesDropTarget = null;
	private DropTarget getThisDropTarget() {
		if (this.favoritesFIlesDropTarget==null) {
			favoritesFIlesDropTarget = new FavoriteFilesDropTarget(this.mainFrame);
		}
		return this.favoritesFIlesDropTarget;
	}

	private Map<String,Object> tableOldValueMap = new HashMap<String,Object>();

	private String statusBar_favoriteFilesAmount = "aaFavorite files amount is : ";
	private String dialog_Sure_Delete_Node = "确认删除节点吗？";
	private String dialog_Pls_Input_Name = "请输入节点名称";
	private String dialog_removeFromClass = "确定从当前分类移出吗？";

	private int Max_Num_Opened_Once_Time =10 ; //每次最多可打开文件数

//	private boolean isNotFirstShow = false;   //本面板第一次显示的标识
    public static final int Key_ENTER          = 0;//'\n';
	
    protected void saveRowDataToMap(JTable table, int row, Map<String,Object> map){
    	int columnCount = table.getColumnCount();
    	for (int i = 0; i < columnCount; i++) {
    		map.put(i+"", table.getValueAt(row, i));
		}
    }

    /**
	 * <p>
	 * fetchData:从数据库获取数据，并且在界面做展示控制。
	 * setupView:不从数据库获取数据，只是做见面展示控制。
	 * </p>
	 * 
     */
	public void refreshMainTable(Boolean needScroll2Top) {
	
		TableColumn tc = null;
	    TableColumnModel tcm = mainTable.getColumnModel(); 
        for(int i=0; i <MainTable_Columns_Width.length; i++)   {
            tc   =   tcm.getColumn(i);
            tc.setPreferredWidth(MainTable_Columns_Width[i]); 
            
        }

        //斑马线
        this.getMainTable().showZebraCross();

        // column size to right
        tc = tcm.getColumn( MainTable_Column_Index_AccessedTimes );//column name
//        DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) tc.getCellRenderer();
        DefaultTableCellRenderer renderer = new ZebraCrossTableCellRenderer();
        renderer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        tc.setCellRenderer(renderer);
        
        TableCellRenderer myRenderer = new IconTableCellRenderer(mainTable, MainTable_Column_Index_Location, true);
        tc = tcm.getColumn( MainTable_Column_Index_Name );//column name
        tc.setCellRenderer(myRenderer);
        
		final String searchWord = searchWordTextFeild.getText();
		if (doSearch(searchWord, false)<1 && getMainTable().getRowCount()>0 ) {
	        getMainTable().setRowSelectionInterval(0, 0);
		}
		// move table to top
		if (needScroll2Top) {
			DirectorComponentUtils.scrollToRow( getMainTable(), 0);
		}
		//隐藏列(从个人隐私及常用性考虑)
        int[] cols = {MainTable_Column_Index_LastAccessedTime};   //隐藏的列集合
        DirectorComponentUtils.hideTableColumns(mainTable, cols); 
        
		currentStatusInfor = statusBar_favoriteFilesAmount  + getMainTable().getRowCount();
		setStatus(StatusBar_Index_One, currentStatusInfor);
	}
	
	/**
	 * <p>
	 * fetchData:从数据库获取数据，并且在界面做展示控制。
	 * setupView:不从数据库获取数据，只是做见面展示控制。
	 * </p>
	 * 
	 */
    public boolean fetchData() throws SQLException {
		//Connection conn= null;
		//Statement stmt =null;
		//ResultSet rs=null;
		RowSet rs=null;
		try { 
			boolean isFileIncluded = true; //includeDocumentCheckBox.isSelected();
			boolean isProgramIncluded = true; //includeProgramCheckBox.isSelected();
			if (isFileIncluded==false
					&&isProgramIncluded==false){
				PlainTableModel ptm = this.getMainTable().getModel(); //
				ptm.removeAllRows();
				return true;  //if nothing is included;
			}
			
			//conn= ApplicationContext.getInstance().getDataSourceManager().getConnection();
			//获取配置信息
			//stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

			int classId = DirectorConstants.FavoriteFiles_ClassId_Default;  
			int isBuiltin = 1;
			int isLeaf = 0;
			if (this.currentTreeNodeBean!=null) {
				classId = this.currentTreeNodeBean.getClassId();
				isBuiltin =this.currentTreeNodeBean.getIsBuiltin();
				isLeaf =this.currentTreeNodeBean.getIsLeaf();
			}
			
			StringBuffer sb_sql = new StringBuffer("Select");
			//Sql前面部分
			if (classId==DirectorConstants.FavoriteFiles_ClassId_Recent) { //Recent
				sb_sql.append(" top 150") ;
			}

			sb_sql.append(" Typee, Tags, Namee")
			  		.append(",Location, LastAccessed, Times")
			  		.append(" From "+DirectorConstants.FMT_FavoriteFiles ) ;
			//条件部分
			if (classId==DirectorConstants.FavoriteFiles_ClassId_Recent) { //Recent
				sb_sql.append(" Where LastAccessed>'")
				.append(DateUtil.getDateBeforeMonth(8))  //最近一年/半年的
//				.append(" 00:00:00")
				.append("'"); 
			} else if (classId==DirectorConstants.FavoriteFiles_ClassId_Recent_Doc) { //Recent document
				sb_sql.append(" Where LastAccessed>'")
				.append(DateUtil.getDateBeforeMonth(8))
				.append("'")
				.append(" And LCase(typee) not in(").append(DirectorConstants.Program_Exts).append(")"); ; 
			} else if (classId==DirectorConstants.FavoriteFiles_ClassId_Recent_Pro) { //Recent program
				sb_sql.append(" Where LastAccessed>'")
				.append(DateUtil.getDateBeforeMonth(8))
				.append("'")
				.append(" And LCase(typee) in(").append(DirectorConstants.Program_Exts).append(")"); 
				
			} else if (classId==DirectorConstants.FavoriteFiles_ClassId_All) { //all

				//
			} else if (classId==DirectorConstants.FavoriteFiles_ClassId_Doc) { //only document
				sb_sql.append(" Where LCase(typee) not in(").append(DirectorConstants.Program_Exts).append(")");

			} else if (classId==DirectorConstants.FavoriteFiles_ClassId_Pro) { //only program
				sb_sql.append(" Where LCase(typee) in(").append(DirectorConstants.Program_Exts).append(")");

			} else {
				if(isLeaf==1)
					sb_sql.append(" Where Class_id="+classId);
				else
					sb_sql.append(" Where Class_id in(Select Class_Id from " + 
							DirectorConstants.FMT_FavoriteFiles_Class+" Where Pid="+classId+")");
			}
			sb_sql.append(" Order by LastAccessed desc, Times desc");
			log.info(sb_sql);
			//rs=stmt.executeQuery(sb_sql.toString());
			DbBean dbBean = new DbBean(DbBean.DefaultPoolName);
			rs = dbBean.queryForRowSet(sb_sql.toString());
			rs.last();
			int size = rs.getRow();
			rs.beforeFirst();
			
			//数据生成
			Object[][] data = new Object[size][MainTable_Headers.length];
			int rowIndex=-1;
			String str_time = null;
			while (rs.next()) {
				data[++rowIndex][MainTable_Column_Index_Type] = rs.getString("Typee");
				data[rowIndex][MainTable_Column_Index_Tags] = rs.getString("Tags");
				data[rowIndex][MainTable_Column_Index_Name] = rs.getString("Namee");
				data[rowIndex][MainTable_Column_Index_Location] = rs.getString("Location");
				str_time = rs.getString("LastAccessed");
				if (str_time!=null && str_time.length()>18) {
					str_time = str_time.substring(0, 19);
				}
				//ad = sdf.format((sdf.parse(ad)));
				//dbBean.executeUpdate("Update FMT_FavoriteFiles set LastAccessed='"+ad+".000' Where location='"+location+"'");
				data[rowIndex][MainTable_Column_Index_LastAccessedTime] = str_time;   // 改成text类型字段 Formatter.formatDate();
				data[rowIndex][MainTable_Column_Index_AccessedTimes] = rs.getInt("Times");
			}

			//DefaultTableModel dtm = (DefaultTableModel) (this.getMainTable().getModel()).getTableModel();
			//dtm.setDataVector(data, MainTable_Headers);  //following is better.
			PlainTableModel ptm = this.getMainTable().getModel(); //
			ptm.removeAllRows();
			ptm.cancelSorting(); //clearSortingState();
			for (int i = 0; i < data.length; i++) {
				ptm.getTableModel().addRow(data[i]);
			}
    		//1.end of get data
			
			//2.setup view
			refreshMainTable( true );
	        
		}catch (Exception e){
			e.printStackTrace();
			
		} finally {
			//wzw.util.DbUtils.closeQuietly(conn, stmt, null); //rs
		}
		return true;
	}

	public boolean saveData() throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	public void itemStateChanged(ItemEvent e) {
		Object obj = e.getSource();
//		if( obj== includeDocumentCheckBox 
//				   ||obj== includeProgramCheckBox){
//			try {
//				fetchData();
//			} catch (SQLException sqlE) {
//				sqlE.printStackTrace();
//			}
//		}
		
	}

	public void actionPerformed(ActionEvent e) {

		Object obj=e.getSource();
		// toolBar
		if( obj == jpmi_MainTable_Open){
			doOpenFileOrFolder(File_Type_File, true, DirectorComponentUtils.isShiftDown(e) );
			
		}else if( obj == jpmi_MainTable_WebSearch){
			String keyWord = "";
			String t_name = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Name).toString();
			String t_tags = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Tags).toString();
			if (org.apache.commons.lang.StringUtils.isNotBlank(t_tags)) {
				keyWord += t_tags + " ";
			}
			if (t_name.indexOf(".")>0) { //如果有，去掉后面的扩展名
				t_name = t_name.substring(0, t_name.lastIndexOf("."));
			}
			keyWord += t_name;
			
			DirectorComponentUtils.getDefaultWebSearchProvider().searchWebPage(keyWord);
			return;
			
		}else if( obj == jpmi_MainTable_LocalSearch){
			String t_name = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Name).toString();
			if (t_name.indexOf(".")>0) { //如果有，去掉后面的扩展名
				t_name = t_name.substring(0, t_name.lastIndexOf("."));
			}
			
			this.mainFrame.executeLocalSearch(t_name);
			return;
			
		}else if( obj == jpmi_MainTable_OpenPath){
			this.doOpenFileOrFolder(File_Type_Folder, true, DirectorComponentUtils.isShiftDown(e) );
			
		}else if( obj == jpmi_MainTable_OpenPath_In_FileExplorer){ 
			this.doOpenFileOrFolder(File_Type_FolderInFileExplorer, false, false);
//			String fileName = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_Name).toString();
//			String fileUri = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_FileUri).toString();
//			File f = new File(fileUri);
//			String filePath = null;
//			if (f.exists()) {
//				filePath = f.getParent();
//			}else{
//				return ;
//			}
			
		}else if( obj == jpmi_MainTable_AddFileOpenTaskAwoke){
			String fileName = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_Name).toString();
			String fileUri = getMainTable().getModel().getValueAt(getMainTable().getSelectedRow(), MainTable_Column_Index_Location).toString();
			this.mainFrame.getReminderMainPanel().executeAddNewFileOpenAwoke(fileUri,fileName);
  		   
		}else if( obj == jpmi_MainTable_removeFromClass){
			//step: check input 
			int[] selRows = getMainTable().getSelectedRows(); // support multi rows
			if (selRows==null || selRows.length<1) {
				return;
			}
			if(JOptionPane.showConfirmDialog(this, dialog_removeFromClass
					, this.msgDialog_info,JOptionPane.OK_CANCEL_OPTION)
					!=JOptionPane.OK_OPTION)
				return;

			String fileUri = null;
			List<String> fileUriList = new ArrayList<String>();
			for (int i=selRows.length-1; i>-1; i--) {
				fileUri = getMainTable().getModel().getValueAt( selRows[i], MainTable_Column_Index_Location).toString();
				fileUriList.add(fileUri);				
			}
			FavoriteFilesDao ffd = new FavoriteFilesDaoImpl();
			try {
				ffd.setFiles2Class(fileUriList, -1);
				for (int i=selRows.length-1; i>-1; i--) {
					getMainTable().getModel().removeRow(selRows[i]);
				}				
			} catch (SQLException e1) {
				log.error(e1);
			}		
		
		}else if( obj == jpmi_MainTable_Delete){
			
			//step: check input 
			int[] selRows = getMainTable().getSelectedRows(); // support multi rows
			if (selRows==null || selRows.length<1) {
				return;
			}
			
			//step: confirm business, JOptionPane不支持指定默认按钮，只能第一个为默认按钮？？
			//"确认删除选中的["+selRows.length+"]行记录吗？"
			String info = StringUtils.replace(this.msgDialog_infoDelete, "${rowSize}", selRows.length+"");
			if(JOptionPane.showConfirmDialog(this, info
													, this.msgDialog_info,JOptionPane.OK_CANCEL_OPTION)
	 				!=JOptionPane.OK_OPTION)
				return;

			//step: do business
			String fileUri = null;
			DefaultTableModel dtm = (DefaultTableModel) (this.getMainTable().getModel()).getTableModel();
			List<String> fileUriList = new ArrayList<String>();
			for (int i=selRows.length-1; i>-1; i--) {
				fileUri = getMainTable().getModel().getValueAt( selRows[i], MainTable_Column_Index_Location).toString();
				fileUriList.add(fileUri);				
			}
			
			FavoriteFilesDao ffd = new FavoriteFilesDaoImpl();
			try {
				ffd.deleteByLocations(fileUriList);
			
				info = this.msgDialog_infoExecuteSuccess;//"Delete Successfully!";
				for (int i=selRows.length-1; i>-1; i--){  //if successful,remove selected rows.
					dtm.removeRow(selRows[i]);				
				}
			} catch (SQLException e1) {
				e1.printStackTrace();
				info = this.msgDialog_infoExecuteFail; //"Delete Failed!";
			}

			setStatus( StatusBar_Index_One, info);
			//step: give notice,and change status first.
			JOptionPane.showMessageDialog(this, info
												, this.msgDialog_info,JOptionPane.INFORMATION_MESSAGE);
			
		}else if( obj == btnAdd ){
			doAddNewFileToFavorite();
			
		}else if( obj==jpmi_MainTable_Refresh){
	    	try {
				fetchData();
				
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
	    	//e.consume();
			
		}else if( obj==jpmi_MainTable_Search){
			getSearchWordTextFeild().setFocusable(true); 
			getSearchWordTextFeild().requestFocusInWindow();
	    	//e.consume();
		}else if( obj==jpmi_MainTable_EditTags ){
			int row = mainTable.getSelectedRow();
			if (row<0) {
				return;
			}
			JTextField jText = (JTextField) ( (DefaultCellEditor) mainTable.getCellEditor(row, MainTable_Column_Index_Tags)).getComponent();  
			jText.requestFocus();  
			mainTable.editCellAt(row, MainTable_Column_Index_Tags);
			
		}else if( obj==jpmi_MainTable_UpdateLocation ){
			int row = mainTable.getSelectedRow();
			if (row<0) {
				return;
			}
			PlainTableModel pModel = mainTable.getModel();  //
			pModel.setColumnEditable( MainTable_Column_Index_Location , true);
			JTextField jText = (JTextField) ( (DefaultCellEditor) mainTable.getCellEditor(row, MainTable_Column_Index_Location)).getComponent();  
			mainTable.editCellAt(row, MainTable_Column_Index_Location);
			jText.requestFocus(); 
			jText.selectAll();   
			
		}else if( obj==jpmi_Tree_AddBrotherNode){

            //获取选中节点  
            DefaultMutableTreeNode selectedNode  
                = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();  
            //如果节点为空，直接返回  
            if (selectedNode == null) return;  
            //获取该选中节点的父节点  
            DefaultMutableTreeNode parent  
                = (DefaultMutableTreeNode)selectedNode.getParent();  
            //如果父节点为空，直接返回  
            if (parent == null) return;
            TreeNodeBean selNodeBean = (TreeNodeBean)selectedNode.getUserObject();
            //创建一个新节点
            TreeNodeBean treeNodeBean = new TreeNodeBean();
            treeNodeBean.setClassName("NewNode");
            treeNodeBean.setClassId(8);
            treeNodeBean.setIsBuiltin(0);
            treeNodeBean.setLevelId(selNodeBean.getLevelId());
            treeNodeBean.setPid(selNodeBean.getPid());
            treeNodeBean.setIsLeaf(selNodeBean.getIsLeaf());
            treeNodeBean.setOrderId(selNodeBean.getOrderId());
            FavoriteFilesDao ffd = new FavoriteFilesDaoImpl();
            try {
				ffd.insertTreeNode(treeNodeBean);
			} catch (SQLException e1) {
				log.error(e1);
			}
            
            this.currentTreeNodeBean = treeNodeBean;
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(treeNodeBean);
            
            //获取选中节点的选中索引  
            int selectedIndex = parent.getIndex(selectedNode);  
            //在选中位置插入新节点  
            model.insertNodeInto(newNode, parent, selectedIndex + 1);  
            //--------下面代码实现显示新节点（自动展开父节点）-------  
            //获取从根节点到新节点的所有节点  
            TreeNode[] nodes = model.getPathToRoot(newNode);  
            //使用指定的节点数组来创建TreePath  
            TreePath path = new TreePath(nodes);  
            //显示指定TreePath  
            tree.scrollPathToVisible(path);   
		}else if( obj==jpmi_Tree_AddChildNode){

            //获取选中节点  
            DefaultMutableTreeNode selectedNode  
                = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();  
            //如果节点为空，直接返回  
            if (selectedNode == null) return;  
            TreeNodeBean selNodeBean = (TreeNodeBean)selectedNode.getUserObject();
            //创建一个新节点  
            TreeNodeBean treeNodeBean = new TreeNodeBean();
            treeNodeBean.setClassName("NewNode");
            treeNodeBean.setClassId(8);
            treeNodeBean.setIsBuiltin(0);
            treeNodeBean.setLevelId(selNodeBean.getLevelId()+1);
            treeNodeBean.setPid(selNodeBean.getClassId());
            treeNodeBean.setIsLeaf(1);  //selNodeBean.getIsLeaf()
            treeNodeBean.setOrderId(-1);
            FavoriteFilesDao ffd = new FavoriteFilesDaoImpl();
            try {
				ffd.insertTreeNode(treeNodeBean);
			} catch (SQLException e1) {
				log.error(e1);
			}
            
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(treeNodeBean);  
            //直接通过model来添加新节点，则无需通过调用JTree的updateUI方法  
            //model.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());  
            //直接通过节点添加新节点，则需要调用tree的updateUI方法  
            selectedNode.add(newNode);  
            //--------下面代码实现显示新节点（自动展开父节点）-------  
            TreeNode[] nodes = model.getPathToRoot(newNode);  
            TreePath path = new TreePath(nodes);  
            tree.scrollPathToVisible(path);  
            tree.updateUI(); 
		}else if( obj==jpmi_Tree_AddBrotherNode){

            //获取选中节点  
            DefaultMutableTreeNode selectedNode  
                = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();  
            //如果节点为空，直接返回  
            if (selectedNode == null) return;  
            //获取该选中节点的父节点  
            DefaultMutableTreeNode parent  
                = (DefaultMutableTreeNode)selectedNode.getParent();  
            //如果父节点为空，直接返回  
            if (parent == null) return;  
            //创建一个新节点  
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("NewNode");  
            //获取选中节点的选中索引  
            int selectedIndex = parent.getIndex(selectedNode);  
            //在选中位置插入新节点  
            model.insertNodeInto(newNode, parent, selectedIndex + 1);  
            //--------下面代码实现显示新节点（自动展开父节点）-------  
            //获取从根节点到新节点的所有节点  
            TreeNode[] nodes = model.getPathToRoot(newNode);  
            //使用指定的节点数组来创建TreePath  
            TreePath path = new TreePath(nodes);  
            //显示指定TreePath  
            tree.scrollPathToVisible(path);   
		}else if( obj==jpmi_Tree_EditNode){

            TreePath selectedPath = tree.getSelectionPath();  
            if (selectedPath != null)  
            {  
                //编辑选中节点 
//            	tree.setEditable(true);
//                tree.startEditingAtPath(selectedPath);  
//                tree.getCellEditor().addCellEditorListener( this );
            	//目前无法后去改变之后的值，故采用输入框
            	String className=JOptionPane.showInputDialog( this.dialog_Pls_Input_Name, this.currentTreeNodeBean.getClassName());
            	if (className==null || className.trim().length()<1) {
            		return;
				}
            	this.currentTreeNodeBean.setClassName(className);
            	FavoriteFilesDao ffd  = new FavoriteFilesDaoImpl();
            	try {
					ffd.updateTreeNode(this.currentTreeNodeBean);
				} catch (SQLException e1) {
					log.error(e1);
				}
				tree.updateUI();
            	
            }  
		}else if( obj==jpmi_Tree_DelNode){

			if(JOptionPane.showConfirmDialog(this.mainFrame, this.dialog_Sure_Delete_Node,"",JOptionPane.OK_CANCEL_OPTION )==JOptionPane.CANCEL_OPTION)
				return;
            DefaultMutableTreeNode selectedNode  
                = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 
            
            if (selectedNode != null && selectedNode.getParent() != null)  
            {  
            	TreeNodeBean treeNodeBean = (TreeNodeBean) selectedNode.getUserObject();
            	FavoriteFilesDao ffd  = new FavoriteFilesDaoImpl();
            	try {
					ffd.deleteTreeNode(treeNodeBean );
				} catch (SQLException e1) {
					log.error(e1);
				}
                //删除指定节点  
                model.removeNodeFromParent(selectedNode);  
            }  
		} else if( obj==jpmi_Tree_MoveUp){
            DefaultMutableTreeNode selectedNode  
            	= (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 
	        if (selectedNode== null )  
	        	return;

            //获取该选中节点的父节点  
            DefaultMutableTreeNode parent  
                = (DefaultMutableTreeNode)selectedNode.getParent(); 
            //获取选中节点的选中索引  
            int selectedIndex = parent.getIndex(selectedNode);
            if (selectedIndex==0) {
				return; //已经是最顶部了
			}
            //在选中位置插入新节点  
            model.removeNodeFromParent(selectedNode);
            model.insertNodeInto(selectedNode, parent, selectedIndex - 1);  
            
        	TreeNodeBean treeNodeBean = (TreeNodeBean) selectedNode.getUserObject();
        	treeNodeBean.setOrderId(selectedIndex); //-1
        	FavoriteFilesDao ffd  = new FavoriteFilesDaoImpl();
        	try {
				ffd.updateOrderById(treeNodeBean, selectedIndex+1);
			} catch (SQLException e1) {
				log.error(e1);
			}
        	
		} else if( obj==jpmi_Tree_MoveDown){
            DefaultMutableTreeNode selectedNode  
	        	= (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 
	        if (selectedNode== null )  
	        	return;
	
	        //获取该选中节点的父节点  
	        DefaultMutableTreeNode parent  
	            = (DefaultMutableTreeNode)selectedNode.getParent(); 
	        //获取选中节点的选中索引  
	        int childCount = parent.getChildCount();
	        int selectedIndex = parent.getIndex(selectedNode);
	        if (selectedIndex==childCount-1) {
				return; //已经是最底部了
			}
	        //在选中位置插入新节点  
	        model.removeNodeFromParent(selectedNode);
	        model.insertNodeInto(selectedNode, parent, selectedIndex+1 );// + 1  
	        
	    	TreeNodeBean treeNodeBean = (TreeNodeBean) selectedNode.getUserObject();
	    	treeNodeBean.setOrderId(selectedIndex+2); //-1
	    	FavoriteFilesDao ffd  = new FavoriteFilesDaoImpl();
	    	try {
				ffd.updateOrderById(treeNodeBean, selectedIndex+1);
			} catch (SQLException e1) {
				log.error(e1);
			}
	    	
		}
	}

	public void addNewFileToFavorite(String fileUri, String tags) throws SQLException{

		if (tags==null) {
			tags="";
		}
		File file = new File(fileUri);
		String location = file.getPath();
		String namee = file.getName();
		String typee = "";
		if (file.isFile()) {
			int dotPos = namee.lastIndexOf(".");
			if (dotPos>-1) {  // some files have on extension name.
				typee = namee.substring( namee.lastIndexOf("."));	
			}else{
				typee = "";
			}
		}
		
		String dt_string = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(Calendar.getInstance().getTime());
		Vector<String> v_row = new Vector<String>();
		v_row.add(MainTable_Column_Index_Type, typee);
		v_row.add(MainTable_Column_Index_Tags, tags);
		v_row.add(MainTable_Column_Index_Name, namee);
		v_row.add(MainTable_Column_Index_Location, location);
		v_row.add(MainTable_Column_Index_AccessedTimes, "1");
		v_row.add(MainTable_Column_Index_LastAccessedTime, dt_string.substring(0, 19));
		
		DbBean dbBean = new DbBean(DbBean.DefaultPoolName);
		String sql="Select count(0) From "+DirectorConstants.FMT_FavoriteFiles +
					" Where Location='"+location+"'"; //大小写敏感，支持不同OS规则
		int cnt = dbBean.queryForInt(sql);
		if (cnt>0) {  // data exists.
			log.info( fileUri+ " location exists in favorites. finished!");
//			sql="Select Class_Id From "+DirectorConstants.FMT_FavoriteFiles +
//						" Where Location='"+location+"'";
//			int cid = dbBean.queryForInt(sql);
			
			//update last time and ignore times.
			sql="Update "+DirectorConstants.FMT_FavoriteFiles+" set LastAccessed='"
							+ dt_string
							+ "',Class_Id="
							+ currentTreeNodeBean.getClassId()
							+ " Where Location='"+location+"'"; //大小写敏感，支持不同OS规则
			log.info( sql );
			dbBean.executeUpdate(sql);
			
			boolean hasFound=false;
			int rowCount = mainTable.getRowCount();
			//下面使用 PlainTableModel 而不是 mainTable操作。
			PlainTableModel stm = this.getMainTable().getModel(); //
			Object tmp_location = null;
			for (int i = 0; i < rowCount; i++) {
				tmp_location = stm.getValueAt(i, MainTable_Column_Index_Location);
				if (location.equals(tmp_location)) {
					stm.setValueAt(dt_string.substring(0, 19), i, MainTable_Column_Index_LastAccessedTime);
					stm.moveRow(i, i, 0); //move to first one and set selected
					hasFound=true;
					break;
				}
			}
			if (hasFound==false  
					&&currentTreeNodeBean.getClassId()!=DirectorConstants.FavoriteFiles_ClassId_All
					&&currentTreeNodeBean.getClassId()!=DirectorConstants.FavoriteFiles_ClassId_Doc
					&&currentTreeNodeBean.getClassId()!=DirectorConstants.FavoriteFiles_ClassId_Pro ) { //not found				
				DefaultTableModel dtm = (DefaultTableModel) (this.getMainTable().getModel()).getTableModel();
				dtm.insertRow(0, v_row);
			}
			//return ;  //end of modify
		} else {
			sql="Insert Into "+DirectorConstants.FMT_FavoriteFiles+"(Typee, Tags, Namee" +
					", Location, LastAccessed, Times,Class_Id)" +
					" Values('"+typee+"','"+tags+"','"+ namee+"'" +
							",'"+location+"','"+dt_string+"',1, "+currentTreeNodeBean.getClassId()+")";
			log.info( sql );
			try {
				dbBean.executeUpdate( sql );
				
				DefaultTableModel dtm = (DefaultTableModel) (this.getMainTable().getModel()).getTableModel();
				dtm.insertRow(0, v_row);
				
			} catch (SQLException e1) {
				e1.printStackTrace();
				throw e1;
			}
		}
		currentStatusInfor = statusBar_favoriteFilesAmount  + getMainTable().getRowCount();
		setStatus(StatusBar_Index_One, currentStatusInfor);
	}
	
	private void doAddNewFileToFavorite() {
		String tags = this.getTagsTextFeild().getText();
		String uri = null;
		if( getUrlSelector().getSelectedItem()==null ){
			JOptionPane.showMessageDialog(this,"请选择路径！");
			getUrlSelector().requestFocus();
			return;
		} else {
			//ts_path = getPath().getSelectedItem().toString();
			uri = ((JFileTree)((JTreeComboBox)getUrlSelector()).getTree()).getSelectFile().getPath() ;
		}

		try {
			addNewFileToFavorite(uri, tags);
			// "Add to favorite successfully!"
			JOptionPane.showMessageDialog(this, this.msgDialog_infoExecuteSuccess, this.msgDialog_info,JOptionPane.INFORMATION_MESSAGE);

		} catch (Exception e1) {
			JOptionPane.showMessageDialog(this,e1.getMessage(),"数据库操作失败",JOptionPane.ERROR_MESSAGE);
			e1.printStackTrace();
			return;
		} finally {
		}
	}

	private static String File_Type_File = "file";
	private static String File_Type_Folder = "folder";
	private static String File_Type_FolderInFileExplorer = "folder_In_FileExplorer";
	
	/**
	 * @deprecated
	 * @param openMulti
	 */
	private void doOpenFileOrFolder(boolean openMulti) {
		doOpenFileOrFolder(File_Type_File, openMulti, false);
	}
	
	private void doOpenFileOrFolder(String type, boolean openMulti, boolean isShiftDown) { 
//		if (getMainTable().getSelectedRow()<0) {
//			return ;
//		}
		int selRows[] = { getMainTable().getSelectedRow() };
		if (openMulti) {
			selRows = getMainTable().getSelectedRows();
		}
		
		if (selRows==null || selRows.length<1) {
			return;
		}
		
		String fileUri = null;
		String filePath = null;
		File f = null;
		String dt_string = null;
		String sql= null;
		DbBean dbBean = new DbBean(DbBean.DefaultPoolName);
		PlainTableModel ptm = null;
		int cnt = 1;
		boolean hasFileOpened = false;
		for (int selRow : selRows) {	
			//String fileName = getMainTable().getModel().getValueAt(selRow, MainTable_Column_Index_Name).toString();
			fileUri = getMainTable().getModel().getValueAt(selRow, MainTable_Column_Index_Location).toString();
			filePath = null;
			f = new File(fileUri);
			if (f.exists()) {
				filePath = f.getParent();
				hasFileOpened = true;
			}else{
				continue ;
			}
			if (File_Type_FolderInFileExplorer.equals(type)) {
				this.mainFrame.getMainTabbedPane().setSelectedIndex( MainFrame.MainTabPane_ResourceMasterMainPanel_Index ); // add 
				this.mainFrame.getResourceMasterMainPanel().getMainTabbedPane().setSelectedIndex( ResourceMasterMainPanel.MainTabPane_FileExplorer_Index ); // add 
				this.mainFrame.getResourceMasterMainPanel().getFileExplorerPanel().setCurrentFolder(filePath, null);
				
			}else if (File_Type_Folder.equals(type)) {
				DirectorFileUtils.openFileLocationQuietly(fileUri);
				
			} else {
				DirectorFileUtils.openFileQuietly(fileUri); // + File.separator + fileName
			}
			
			//日期类型改成text，因为date字段不支持毫秒.BTW:实事证明，2个同时打开的毫秒级也分不开，故不再更细的标识
			dt_string = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss").format(Calendar.getInstance().getTime()); //.sss
			sql="Update "+DirectorConstants.FMT_FavoriteFiles
						+" set LastAccessed='"+dt_string+"',Times=Times+1 Where Location='"+fileUri+"'";
			log.info( sql );
			try {
				ptm = this.getMainTable().getModel();
				/// DefaultTableModel dtma = (DefaultTableModel) stm.getTableModel();
				Object times = ptm.getValueAt(selRow, MainTable_Column_Index_AccessedTimes);
				if (times==null) {
					times = 1;
				}
	//			stm.clearSortingState();
				log.info("update lastAccessedTime--selRow="+selRow + ",old value="+ptm.getValueAt( selRow, MainTable_Column_Index_LastAccessedTime));
				//最后修改当前排序行。先修改访问次数，再修改访问时间，否则改了时间行数变了(因为一般都按照访问时间排序，这点要完善下)
				//能否有函数先获取行对象，再用行对象修改，而不是使用行号修改?
				ptm.setValueAt( Integer.parseInt(times.toString())+1, selRow, MainTable_Column_Index_AccessedTimes);
				ptm.setValueAt(dt_string.substring(0, 19), selRow, MainTable_Column_Index_LastAccessedTime);
	//			stm.sortingStatusChanged();
				ptm.moveRow(selRow, selRow, 0); //这个必须要，不会自动上移。move to first one and set selected
				getMainTable().setRowSelectionInterval(0, 0);	
				
				dbBean.executeUpdate( sql );			
				log.info( "opening file finished!" );
				
			} catch (SQLException e1) {
				//JOptionPane.showMessageDialog(this,e1.getMessage(),"数据库操作失败",JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
				/// return;
			}
			//达到最大打开数
			if( ++cnt> Max_Num_Opened_Once_Time ){
				break;
			}
		}
		//打开完成后，判断是否需要最小化自己
		if ( hasFileOpened
				&& !File_Type_FolderInFileExplorer.equals(type)
				&& ( (isShiftDown && !"1".equals(DirectorConstants.MinimizeFrame_After_OpenFileOrFolder_Value))
						|| (!isShiftDown && "1".equals(DirectorConstants.MinimizeFrame_After_OpenFileOrFolder_Value)) )) {
	        
			this.mainFrame.setExtendedState( JFrame.ICONIFIED );//最小化.NORMAL
		}
	}
	
	public void mouseClicked(MouseEvent e) {
		Object obj = e.getSource() ; 
		if(obj==getMainTable()){
	        //记录进入编辑状态前单元格得数据，并且在切换之后设置为不可编辑
			if(mainTable.getSelectedRow()<=mainTable.getRowCount()
					&& mainTable.getSelectedRow()>-1 ){
				//Object tableOldValue = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Tags)+"";
				//tableOldValueMap.put(MainTable_Column_Index_Tags+"", tableOldValue);
				saveRowDataToMap(mainTable, mainTable.getSelectedRow(), tableOldValueMap);
				PlainTableModel pModel = mainTable.getModel();
				pModel.setColumnEditable( MainTable_Column_Index_Location , false);
			}
			// 双击
			if(!e.isPopupTrigger() && e.getClickCount()==2) {
				doOpenFileOrFolder(File_Type_File, false, e.isShiftDown());
			}
			e.consume();
			
		}else if(obj==getLeftTree()){
			Object treeNodeBean =  ((DefaultMutableTreeNode) tree
					.getLastSelectedPathComponent()).getUserObject() ;
			if (treeNodeBean==null) {
				return;
			}
			this.currentTreeNodeBean = (TreeNodeBean)treeNodeBean;
			
			if(!e.isPopupTrigger() && (e.getClickCount()==2||e.getClickCount()==1) ) {
	
				try {
					fetchData();
				} catch (SQLException sqlE) {
					sqlE.printStackTrace();
				}
			}
		}
	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	private TreeNodeBean currentTreeNodeBean = null;
	public void mouseReleased(MouseEvent e) {
		Object obj = e.getSource() ;
		if(obj==getMainTable()){
			// record old value.
			if(mainTable.getSelectedRow()<=mainTable.getRowCount()
					&& mainTable.getSelectedRow()>-1 ){
//				Object tableOldValue = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Tags)+"";
//				tableOldValueMap.put(MainTable_Column_Index_Tags+"", tableOldValue);
				saveRowDataToMap(mainTable, mainTable.getSelectedRow(), tableOldValueMap);
			}
			// 在Table上右击鼠标
			//System.out.println ( " getPopupMenuForTable 1");
			if( e.getButton() == MouseEvent.BUTTON3 ) {	//显示弹出菜单
				Object obj_name = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Name);
				if (obj_name==null) {
					this.jpmi_MainTable_WebSearch.setVisible(false);
					this.jpmi_MainTable_LocalSearch.setVisible(false);
				}else{

					String keyWord = "";
					String t_name = obj_name.toString();
					String t_tags = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Tags).toString();
					if (org.apache.commons.lang.StringUtils.isNotBlank(t_tags)) {
						keyWord += t_tags + " ";
					}
					if (t_name.indexOf(".")>0) { //如果有，去掉后面的扩展名
						t_name = t_name.substring(0, t_name.lastIndexOf("."));
					}
					keyWord += t_name;
					
					this.jpmi_MainTable_WebSearch.setText(StringUtils.replace(jpmi_MainTable_WebSearch_Text,"${name}", keyWord) );
					this.jpmi_MainTable_WebSearch.setVisible(true);

					this.jpmi_MainTable_LocalSearch.setText(StringUtils.replace(jpmi_MainTable_LocalSearch_Text,"${name}",t_name) );
					this.jpmi_MainTable_LocalSearch.setVisible(true);
				}
				//System.out.println (getTable().getX()+e.getX());
				//getPopupMenuForTable().locate( getTable().getX()+e.getX(), getTable().getY()+e.getY() );
				//getPopupMenuForTable().setVisible( true );
				getPopupMenuForTable().setSelected(null);
				getPopupMenuForTable().show( e.getComponent(), e.getX(), e.getY() );
				
			}
		}else if(obj==getLeftTree()){ 
			if( e.getButton() == MouseEvent.BUTTON3 ) {	//显示弹出菜单 
				Object userObj =   ((DefaultMutableTreeNode) tree
						.getLastSelectedPathComponent()).getUserObject() ;
				if(userObj==null)
					return;
				TreeNodeBean treeNodeBean = (TreeNodeBean) userObj;
				this.currentTreeNodeBean = treeNodeBean;
				getPopupMenuForTree().setSelected(null);
				getPopupMenuForTree().show( e.getComponent(), e.getX(), e.getY() );
				
			}
		}
		
	}


	private JPopupMenu popupMenuForTable;
	private JMenuItem jpmi_MainTable_Open;
	private JMenuItem jpmi_MainTable_OpenPath;
	private JMenuItem jpmi_MainTable_OpenPath_In_FileExplorer;
	private JMenuItem jpmi_MainTable_WebSearch;
	private JMenuItem jpmi_MainTable_LocalSearch;
	private JMenuItem jpmi_MainTable_Search;
	private JMenuItem jpmi_MainTable_Refresh;
	private JMenuItem jpmi_MainTable_EditTags;
	private JMenuItem jpmi_MainTable_UpdateLocation;
	private JMenuItem jpmi_MainTable_Delete;
	private JMenu jpmi_MainTable_SetClass;
	private JMenuItem jpmi_MainTable_removeFromClass;
	
	private JPopupMenu popupMenuForTree;
	private JMenuItem jpmi_Tree_AddBrotherNode;
	private JMenuItem jpmi_Tree_AddChildNode;
	private JMenuItem jpmi_Tree_EditNode;
	private JMenuItem jpmi_Tree_DelNode;
	private JMenuItem jpmi_Tree_MoveUp;
	private JMenuItem jpmi_Tree_MoveDown;

	private String jpmi_MainTable_WebSearch_Text;
	private String jpmi_MainTable_LocalSearch_Text;
	
	
	/**
	 * Table的弹出式菜单
	 */
	private JPopupMenu getPopupMenuForTable(){
		
		if(popupMenuForTable == null){
			popupMenuForTable = new JPopupMenu();
			
			jpmi_MainTable_Open = new JMenuItem();
			jpmi_MainTable_Open.setText("open");
			jpmi_MainTable_Open.addActionListener( this );
			jpmi_MainTable_Open.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK) );
			
			jpmi_MainTable_OpenPath = new JMenuItem();
			jpmi_MainTable_OpenPath.setText("open path");
			jpmi_MainTable_OpenPath.addActionListener( this );
			jpmi_MainTable_OpenPath.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_P,Event.CTRL_MASK) );
			
			jpmi_MainTable_OpenPath_In_FileExplorer = new JMenuItem();
			jpmi_MainTable_OpenPath_In_FileExplorer.setText("open path in file explorer");
			jpmi_MainTable_OpenPath_In_FileExplorer.addActionListener( this );
			jpmi_MainTable_OpenPath_In_FileExplorer.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_E,Event.CTRL_MASK) );
			
			jpmi_MainTable_EditTags = new JMenuItem();
			jpmi_MainTable_EditTags.setText("Edit tags");
			jpmi_MainTable_EditTags.addActionListener( this );
			//jpmi_MainTable_EditTags.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_D,Event.CTRL_MASK) );
			
			jpmi_MainTable_UpdateLocation = new JMenuItem();
			jpmi_MainTable_UpdateLocation.setText("Change location");
			jpmi_MainTable_UpdateLocation.addActionListener( this );
			//jpmi_MainTable_UpdateLocation.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_D,Event.CTRL_MASK) );
			
			jpmi_MainTable_Delete = new JMenuItem();
			jpmi_MainTable_Delete.setText("delete");
			jpmi_MainTable_Delete.addActionListener( this );
			jpmi_MainTable_Delete.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_D,Event.CTRL_MASK) );
			
			jpmi_MainTable_removeFromClass = new JMenuItem();
			jpmi_MainTable_removeFromClass.setText("removeFromClass");
			jpmi_MainTable_removeFromClass.addActionListener( this );
			
			jpmi_MainTable_SetClass = new JMenu("设置到分类");
//			jpmi_MainTable_SetClass.setText("设置到分类");
//			jpmi_MainTable_SetClass.addActionListener( this );
			
			jpmi_MainTable_Refresh = new JMenuItem();
			jpmi_MainTable_Refresh.setText("Refresh");
			jpmi_MainTable_Refresh.addActionListener( this );
			jpmi_MainTable_Refresh.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F5, Modifier.FINAL) );
			
			jpmi_MainTable_WebSearch = new JMenuItem();
			jpmi_MainTable_WebSearch.setText("Web Search ...");
			jpmi_MainTable_WebSearch.addActionListener( this );
			//jpmi_MainTable_WebSearch.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F,Event.CTRL_MASK) );
			
			jpmi_MainTable_LocalSearch = new JMenuItem();
			jpmi_MainTable_LocalSearch.setText("Local Search ...");
			jpmi_MainTable_LocalSearch.addActionListener( this );
			
			jpmi_MainTable_Search = new JMenuItem();
			jpmi_MainTable_Search.setText("Find...");
			jpmi_MainTable_Search.addActionListener( this );
			jpmi_MainTable_Search.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F,Event.CTRL_MASK) );
			
			popupMenuForTable.add( jpmi_MainTable_Open );
			popupMenuForTable.add( jpmi_MainTable_OpenPath );
			popupMenuForTable.add( jpmi_MainTable_OpenPath_In_FileExplorer );
			popupMenuForTable.addSeparator();
			popupMenuForTable.add( getAddFileOpenTaskAwokeMenuItem() );
			popupMenuForTable.addSeparator();
			popupMenuForTable.add( jpmi_MainTable_WebSearch );
			popupMenuForTable.add( jpmi_MainTable_LocalSearch );
			popupMenuForTable.add( jpmi_MainTable_Search );
			popupMenuForTable.add( jpmi_MainTable_Refresh );
			popupMenuForTable.addSeparator();
			popupMenuForTable.add( jpmi_MainTable_EditTags );
			popupMenuForTable.add( jpmi_MainTable_UpdateLocation );
			popupMenuForTable.add( jpmi_MainTable_SetClass );
			popupMenuForTable.add( jpmi_MainTable_removeFromClass );
			popupMenuForTable.add( jpmi_MainTable_Delete );
			
		}

		int clsId = currentTreeNodeBean.getClassId();
		if (clsId==DirectorConstants.FavoriteFiles_ClassId_All 
				|| clsId==DirectorConstants.FavoriteFiles_ClassId_Doc 
				|| clsId==DirectorConstants.FavoriteFiles_ClassId_Pro ) {
			jpmi_MainTable_removeFromClass.setEnabled(false);
		}else{
			jpmi_MainTable_removeFromClass.setEnabled(true);
		}
		
		//root
		jpmi_MainTable_SetClass.removeAll();
		int cnt = root.getChildCount();
		DefaultMutableTreeNode treeNode = null;
		DefaultMutableTreeNode treeNode2 = null;
		TreeNodeBean treeNodeBean = null;
		for (int i = 0; i < cnt; i++) {
			treeNode = (DefaultMutableTreeNode) root.getChildAt(i);
			treeNodeBean = (TreeNodeBean)treeNode.getUserObject();
			if (treeNodeBean.getClassId()==DirectorConstants.FavoriteFiles_ClassId_All
				  ||treeNodeBean.getClassId()==DirectorConstants.FavoriteFiles_ClassId_Recent) { //默认的所有收藏or最近使用
				continue;
			}
			JMenu jMenu = new JMenu(treeNodeBean.getClassName());
			jpmi_MainTable_SetClass.add(jMenu);
			int cnt2 = treeNode.getChildCount();
			
			for (int j = 0; j < cnt2; j++) {
				treeNode2 = (DefaultMutableTreeNode) treeNode.getChildAt(j);
				treeNodeBean = (TreeNodeBean)treeNode2.getUserObject();
				if (treeNodeBean.getClassId()==DirectorConstants.FavoriteFiles_ClassId_Doc
						||treeNodeBean.getClassId()==DirectorConstants.FavoriteFiles_ClassId_Pro) { //所有文档所有程序
					continue;
				}
				JMenuItem jMenuItem = new JMenuItem(treeNodeBean.getClassName());
				final TreeNodeBean tmp_treeNodeBean = treeNodeBean;
				jMenuItem.addActionListener(new ActionListener(){
					@Override
					public void actionPerformed(ActionEvent e) {
						//step: check input 
						int[] selRows = getMainTable().getSelectedRows(); // support multi rows
						if (selRows==null || selRows.length<1) {
							return;
						}
						String fileUri = null;
						List<String> fileUriList = new ArrayList<String>();
						for (int i=selRows.length-1; i>-1; i--) {
							fileUri = getMainTable().getModel().getValueAt( selRows[i], MainTable_Column_Index_Location).toString();
							fileUriList.add(fileUri);				
						}
						int classId = tmp_treeNodeBean.getClassId();
						FavoriteFilesDao ffd = new FavoriteFilesDaoImpl();
						try {
							ffd.setFiles2Class(fileUriList, classId);
							int clsId = currentTreeNodeBean.getClassId();
							if (clsId!=DirectorConstants.FavoriteFiles_ClassId_All 
									&& clsId!=DirectorConstants.FavoriteFiles_ClassId_Doc 
									&& clsId!=DirectorConstants.FavoriteFiles_ClassId_Pro ) {
								for (int i=selRows.length-1; i>-1; i--) {
									getMainTable().getModel().removeRow(selRows[i]);
								}
							}
							
						} catch (SQLException e1) {
							log.error(e1);
						}
						
					}
				});
				jMenu.add(jMenuItem);
			}
		}
		return popupMenuForTable;		
	}
 

	/**
	 * Table的弹出式菜单
	 */
	private JPopupMenu getPopupMenuForTree(){
		
		if(popupMenuForTree == null){
			popupMenuForTree = new JPopupMenu();

			jpmi_Tree_AddBrotherNode = new JMenuItem();
			jpmi_Tree_AddBrotherNode.setText("增加同级节点");
			jpmi_Tree_AddBrotherNode.addActionListener( this );
			
			jpmi_Tree_AddChildNode = new JMenuItem();
			jpmi_Tree_AddChildNode.setText("增加子节点");
			jpmi_Tree_AddChildNode.addActionListener( this );
			//jpmi_Tree_AddChildNode.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK) );
			
			jpmi_Tree_EditNode = new JMenuItem();
			jpmi_Tree_EditNode.setText("编辑节点");
			jpmi_Tree_EditNode.addActionListener( this );
			//jpmi_Tree_EditNode.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK) );
			
			jpmi_Tree_DelNode = new JMenuItem();
			jpmi_Tree_DelNode.setText("删除节点");
			jpmi_Tree_DelNode.addActionListener( this );
			//jpmi_Tree_DelNode.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK) );

			jpmi_Tree_MoveUp = new JMenuItem();
			jpmi_Tree_MoveUp.setText("上移");
			jpmi_Tree_MoveUp.addActionListener( this );

			jpmi_Tree_MoveDown = new JMenuItem();
			jpmi_Tree_MoveDown.setText("下移");
			jpmi_Tree_MoveDown.addActionListener( this );
			
			popupMenuForTree.add( jpmi_Tree_AddBrotherNode );
			popupMenuForTree.add( jpmi_Tree_AddChildNode );
			popupMenuForTree.add( jpmi_Tree_EditNode );
			popupMenuForTree.add( jpmi_Tree_DelNode );
			popupMenuForTree.addSeparator();
			popupMenuForTree.add( jpmi_Tree_MoveUp );
			popupMenuForTree.add( jpmi_Tree_MoveDown );
			
			
		}

		jpmi_Tree_EditNode.setEnabled(true);
		jpmi_Tree_DelNode.setEnabled(true);
		jpmi_Tree_AddBrotherNode.setEnabled(true);
		jpmi_Tree_AddChildNode.setEnabled(true);
		jpmi_Tree_MoveUp.setEnabled(true);
		jpmi_Tree_MoveDown.setEnabled(true);
		
//		int isBuiltin = currentTreeNodeBean.getIsBuiltin();
//		int isLeaf = currentTreeNodeBean.getIsLeaf();
		if (currentTreeNodeBean!=null && currentTreeNodeBean.getIsBuiltin()==1) {
			jpmi_Tree_EditNode.setEnabled(false);
			jpmi_Tree_DelNode.setEnabled(false);
			jpmi_Tree_AddChildNode.setEnabled(false);
			jpmi_Tree_MoveUp.setEnabled(false);
			jpmi_Tree_MoveDown.setEnabled(false);
			if (currentTreeNodeBean!=null && currentTreeNodeBean.getIsLeaf()==1) {
				jpmi_Tree_AddBrotherNode.setEnabled(false);
			}
		}
		if (currentTreeNodeBean!=null && currentTreeNodeBean.getIsLeaf()==1) {
			jpmi_Tree_AddChildNode.setEnabled(false);
		}
		//不能移到默认分类上方
		if(currentTreeNodeBean!=null 
				&& currentTreeNodeBean.getLevelId()==1 
				&& currentTreeNodeBean.getOrderId()==2){
			jpmi_Tree_MoveUp.setEnabled(false);
		}
		
		return popupMenuForTree;		
	}
	public void stateChanged(ChangeEvent e) {
		
	}
	
	public void keyPressed(KeyEvent e) {
		int keyCode = e.getKeyCode();
		Object obj = e.getSource();
		if (obj == mainTable) {
			if(mainTable.getSelectedRow()<=mainTable.getRowCount()
					&& mainTable.getSelectedRow()>-1 ){
				//Object tableOldValue = mainTable.getValueAt(mainTable.getSelectedRow(), MainTable_Column_Index_Tags)+"";
				//tableOldValueMap.put(MainTable_Column_Index_Tags+"", tableOldValue);
				saveRowDataToMap(mainTable, mainTable.getSelectedRow(), tableOldValueMap);
			}
		}
		
		//System.out.println("11111111111111--"+e.getKeyCode());
	    if (e.getKeyCode() == KeyEvent.VK_ENTER
	    		&& (obj==mainTable ||obj==searchWordTextFeild) ) {
    		//System.out.println("2222222222222");
	    	int selRow = getMainTable().getSelectedRow(); //获得开始回车所在的行。
    		log.info("selRow="+selRow);
	    	if (selRow>-1 && selRow<=mainTable.getRowCount()) {
	    		// keyPressed换行前调用， keyTyped换行后调用
		    	//getTable().setRowSelectionInterval(selRow, selRow);
	    		saveRowDataToMap(mainTable, mainTable.getSelectedRow(), tableOldValueMap);
				doOpenFileOrFolder(File_Type_File, false, e.isShiftDown());
		    	e.consume();
			} else { //没有选中时候回车，则选择第一条
		        if (getMainTable().getRowCount()>0) {
		        	getMainTable().setRowSelectionInterval(0, 0);
		        }
			}
	    	
	    }else if (e.getKeyCode() == KeyEvent.VK_DOWN
	    		&& obj==searchWordTextFeild) {
	    	if (getMainTable().getRowCount()>0) {
		    	getMainTable().requestFocus();
		    	getMainTable().setRowSelectionInterval(0, 0);
		    	//DefaultTableModel dtm = (DefaultTableModel) ((SortableTableModel)getTable().getModel()).getTableModel();
		    }
	    	
	    } else if(e.getKeyCode() == KeyEvent.VK_I
	    		&& obj==mainTable ){ //input key word
	    	getSearchWordTextFeild().requestFocus();
	    	e.consume();
	    	
	    }else if(e.getKeyCode() == KeyEvent.VK_F5
	    		&& obj==mainTable ){ //refresh
	    	try {
				fetchData();
				
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
	    	e.consume();
	    	
	    }else if (keyCode == KeyEvent.VK_F && e.isControlDown()
	    		&& (obj==mainTable||obj==tree||obj==this) ) {
			getSearchWordTextFeild().setFocusable(true); 
			getSearchWordTextFeild().requestFocusInWindow();
	    	e.consume();
		}
	} 


	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void update(Observable o, Object arg) {

		super.update(o, arg);
		
		//System.out.println(Locale.getDefault());
		ResourceBundle bundle = I18nUtils.getBundle(DirectorConstants.I18n_Language_Name);

		lbl_tags.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "lbl_tags.Text"));
		lbl_location.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "lbl_location.Text"));
		//lbl_find=new JLabel(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "lbl_find.Text"));
		//lbl_find.putClientProperty("html.disable", Boolean.TRUE);
		lbl_find.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "lbl_find.Text"));
		lbl_note.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "lbl_note.Text"));
		//includeDocumentCheckBox.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "includeDocumentCheckBox.Text"));
		//includeProgramCheckBox.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "includeProgramCheckBox.Text"));
		
		btnAdd.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "btnAdd.Text"));
		
		//table
	    Vector<String> columnIdentifiers = new Vector<String>();
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "table.col00.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "table.col01.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "table.col02.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "table.col03.Text"));
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "table.col05.Text")); //标识应该用表意的英文
	    columnIdentifiers.add(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "table.col04.Text"));
	    DefaultTableModel dtm = (this.getMainTable().getModel()).getTableModel();
	    dtm.setColumnIdentifiers(columnIdentifiers);
	    
	    refreshMainTable( false );
	    rightScrollPanel.setToolTipText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "rightScrollPanel.ToolTipText"));
	    searchWordTextFeild.setToolTipText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "searchWordTextFeild.ToolTipText"));
	    //resize table columns
//	    TableColumn tc = null;
//	    TableColumnModel tcm = mainTable.getColumnModel(); 
//        for(int i=0; i < MainTable_Columns_Width.length-1; i++)   { // ?-1
//            tc   =   tcm.getColumn(i);
//            tc.setPreferredWidth(MainTable_Columns_Width[i]); 
//        }
        
        // popup menu for table 
        getPopupMenuForTable();
        jpmi_MainTable_Open.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_Open.Text"));
        jpmi_MainTable_OpenPath.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_OpenPath.Text"));
        jpmi_MainTable_OpenPath_In_FileExplorer.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_OpenPath_In_FileExplorer.Text"));
        jpmi_MainTable_WebSearch_Text = I18nUtil.getBundleString(bundle, DirectorPanel.class, "jpmi_MainTable_WebSearch.Text");
        jpmi_MainTable_LocalSearch_Text = I18nUtil.getBundleString(bundle, DirectorPanel.class, "jpmi_MainTable_LocalSearch.Text");
        jpmi_MainTable_Search.setText(I18nUtil.getBundleString(bundle, DirectorPanel.class, "jpmi_MainTable_Search.Text"));
        jpmi_MainTable_Refresh.setText(I18nUtil.getBundleString(bundle, DirectorPanel.class, "jpmi_MainTable_Refresh.Text"));
        jpmi_MainTable_EditTags.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_EditTags.Text"));
        jpmi_MainTable_UpdateLocation.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_UpdateLocation.Text"));
        jpmi_MainTable_Delete.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_Delete.Text"));
        jpmi_MainTable_removeFromClass.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_removeFromClass.Text"));
        
        getPopupMenuForTree();
        jpmi_MainTable_SetClass.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_MainTable_SetClass.Text"));
        jpmi_Tree_AddBrotherNode.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_Tree_AddBrotherNode.Text"));
        jpmi_Tree_AddChildNode.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_Tree_AddChildNode.Text"));
        jpmi_Tree_EditNode.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_Tree_EditNode.Text"));
        jpmi_Tree_DelNode.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_Tree_DelNode.Text"));
        jpmi_Tree_MoveUp.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_Tree_MoveUp.Text"));
        jpmi_Tree_MoveDown.setText(I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "jpmi_Tree_MoveDown.Text"));
        dialog_Sure_Delete_Node = I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "dialog_Sure_Delete_Node.Text");
        dialog_Pls_Input_Name = I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "dialog_Pls_Input_Name.Text");
        dialog_removeFromClass = I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "dialog_removeFromClass.Text");
        
        statusBar_favoriteFilesAmount = I18nUtil.getBundleString(bundle, FavoriteFilesMainPanel.class, "statusBar_favoriteFilesAmount.Text");     
		this.currentStatusInfor = statusBar_favoriteFilesAmount + getMainTable().getRowCount();
		/// this.setStatus(StatusBar_Index_One, currentStatusInfor);
 
	}

	@Override
	public void editingCanceled(ChangeEvent e) {
		// TODO Auto-generated method stub
		System.out.println("=======editingCanceled");
	}

	@Override
	public void editingStopped(ChangeEvent e) {
		// System.out.println("=======编辑结束")
		System.out.println("=======editingStopped");
		
		tree.updateUI();
		 //获取选中节点  
        DefaultMutableTreeNode selectedNode  
            = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();  
        //如果节点为空，直接返回  
        if (selectedNode == null) 
        	return;  
        //selectedNode.get
        this.currentTreeNodeBean = (TreeNodeBean) selectedNode.getUserObject();
		int classId = this.currentTreeNodeBean.getClassId();
		String className = this.currentTreeNodeBean.getClassName();
		//tree.getTreeCellEditorComponenet().
        
		System.out.println("=======editingStopped");
		
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		Object eventObj = e.getSource();
		if (eventObj == getMainTable()) {
	        String tipStr=null;
			int row = getMainTable().rowAtPoint(e.getPoint());
	        int column = getMainTable().columnAtPoint(e.getPoint());
	        if (column==MainTable_Column_Index_Tags
	        		||column==MainTable_Column_Index_Name
	        		||column==MainTable_Column_Index_Location) {
		        Object val=getMainTable().getValueAt(row, column);
		        if (val!=null) {
		        	tipStr = val.toString();
				}
			} else if(column==MainTable_Column_Index_AccessedTimes){ //做特殊处理
		        Object val=getMainTable().getValueAt(row, MainTable_Column_Index_LastAccessedTime);
		        if (val!=null) {
		        	tipStr = val.toString();
				}
			}
	        if( tipStr!=null && "".equals(tipStr.trim()) ){
	        	tipStr = null;
	        }
        	getMainTable().setToolTipText(tipStr);
		}
	}
	
} // @jve:decl-index=0:visual-constraint="10,10"
